﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SharedGenomics.Domain
{
    public class DataColumnType<T> : DataColumnTypeBase
    {
        #region Private Members

        private Func<string, T> _transform;

        #endregion

        #region Constructors

        public DataColumnType(string name, Func<string, T> transform, bool unique, bool nullable)
            : base(name, unique, nullable)
        {
            this.Transform = transform;
            this.DataType = typeof(T);
        }

        #endregion

        public override object ResolveValue(string input)
        {
            T resolved = this.Transform(input);
            return this.ApplyMap(resolved);
        }

        public override void CreateMap<MT>(params KeyValuePair<string, MT>[] mappings)
        {
            IEnumerable<KeyValuePair<T, MT>> transformedMappings;

            try
            {
                //immediately evaluate the transform to catch any input argument errors
                transformedMappings = mappings.Select(kvp => new KeyValuePair<T, MT>((T)this.ResolveValue(kvp.Key), kvp.Value)).ToArray();
            }
            catch (Exception)
            {
                throw new ArgumentException("Cannot map from input type to target type");
            }

            Func<T, MT> map = MapFactory.CreateMap(transformedMappings);
            this.SetMap(map);
        }

        internal void AddValues(IEnumerable<T> values)
        {
            if (values != null)
            {
                foreach (T item in values)
                {
                    this.AddValue(item);
                }
            }
        }

        #region Properties

        private Func<string, T> Transform
        {
            get { return this._transform; }
            set
            {
                if (value == null)
                    throw new ArgumentNullException("Transform");

                this._transform = value;
            }
        }

        #endregion

        
    }
}
